﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;

namespace ServiceCollectionProj
{
    /***

      IOC的思想：
        把类当作组件或服务来看待，组件内一定要高内聚，组件之间一定要低耦合，既然要保持低耦合，那就一定不要轻易的去new什么对象。
        那组件之间的交互怎么处理？那最好的方式就是把new的操作交给第三方的治理框架去做。
        比如往大处说的“Dubbo"，”Spring Cloud(服务注册，服务发现，服务自动下线，流量分配，熔断，降级)，往小处说就是ICO容器。

      IOC 容器 能做到什么？
        1. 对接口 和 实现类 实现了由 原来的零散式管理 到 现在的 集中化管理。
        2. 对类之间，类接口之间的关联关系可以采用多种模式注入。（构造器注入，属性注入）
        3. 对实现类的生命周期进行统一管理，能够控制服务的创建，释放和监控。
        4. 对类的依赖由编印时推迟到了运行时。


     * 
     */
    class Program
    {
        static void Main(string[] args)
        {
            // Microsoft.Extensions.DependencyInjection


            //IOC 容器
            ServiceCollection services = new ServiceCollection();

            //服务注册
            // 瞬时，每次调用new 1次
            services.AddTransient<IFly, Pig>();

            // 表示仅 new 1次
            //services.AddSingleton<IFly, Pig>();

            //// 在某个作用域中会 new 1次 (在某个作用域中就是一个单例，每次从同一个容器中获取的实例是相同的)
            //services.AddScoped<IFly, Pig>();



            //Microsoft.Extensions.Logging.Console
            //日志打印 到 控制台 
            services.AddLogging(configure =>
            {
                configure.SetMinimumLevel(LogLevel.Trace);
                configure.AddConsole(cfg => { 
                    cfg.TimestampFormat = "[yyyy-MM-dd HH:mm:ss]";
                });
            });

            var provider = services.BuildServiceProvider();


            var fly = provider.GetService<IFly>();


            fly.Fly();

            Console.ReadKey();
        }
    }

    public interface IFly
    {
        void Fly();
    }

    public class Pig : IFly
    {
        ILogger Logger;

        public Pig(ILoggerFactory loggerFactory)
        {
            this.Logger = loggerFactory.CreateLogger<Pig>();
            Console.WriteLine("执行构造函数");
        }
        public void Fly()
        {
            Logger.LogInformation("开始Fly。。。。");

            Console.WriteLine("风口来了，猪飞起来了！");
        }
    }
}
